# -*- coding: utf-8 -*-

"""
Created on Fri Jun  8 18:43:24 2018

@author: Administrator
"""
#%%

import glob
import os
import shutil
import sys
import pandas as pd

#%%

#----------------------------------------------以下内容为错误信息log记录                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
#主函数要求：import sys
#主函数要求：err_log_path = medi + os.sep + sys._getframe().f_code.co_name + '_err_log.txt'
#主函数要求：其中medi应该根据情况重新定义
#主函数要求：err_log_write(err_log_path,item,i,j)
#主函数要求：每一个出错的部位都设一个i = i + 1

def log_write(log_path,paragr):    
        
    #作用原理：将信息写入txt文件
    #参数说明：paragr是一个双重嵌套list即：paragr[i] 代表要输出的第i行，而paragr[i][j]代表要输出的第i行的第j个元素。
    #返回值说明：无返回值
    #举例：line1 = ['','>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>']；line2 = ['Number Of dir_file： ',i]
    #举例：用上面的line1 line2来构造paragr = [line1,line2]
    #调用：traceback
    #被调用：
    #bug：
    import traceback
    f = open(log_path ,'a')
    for i in range(0,len(paragr)):
        for j in range(0,len(paragr[i])):
            f.write(paragr[i][j])
        f.write('\n')
    traceback.print_exc(file=f)
    f.flush()
    f.close()


def err_log_write(log_path,item,i,j):
    
    #作用：用于记录程序中运行中的异常，以备查看
    #参数说明：err_log_path是指存放异常日志的完整路径（包括日志文件名）
    #参数说明：i报错的在总的循环中是第几个
    #参数说明：j报错次数的记录，用于查看日志共出现多少个错误
    #返回值说明：
    #举例：
    #调用：
    #被调用：

    line1 = ['','@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@']
    line2 = ['Number Of dir_file： ',str(i)]
    line3 = ['Number of Error: ',str(j)]
    line4 = ['Extract Failure: ',item]
    line5 = ['\n' * 1]
    paragr = [line1,line2,line3,line4,line5]
    log_write(log_path,paragr)

#--------------------------------------------以下内容为主函数的子逻辑
def extract_name(item):
    #作用原理：
    #参数说明：
    #参数说明：
    #返回值说明：
    #举例：
    #调用：import os
    #被调用：
    #bug：
    bold_dir = os.path.split(item)[1]
    subj_name = bold_dir.replace('_BOLD','')
    return subj_name
    

#def concatenate_nii(item,output_dir_path):
    #作用原理：暂不使用此软件
    #参数说明：
    #参数说明：
    #返回值说明：
    #举例：
    #调用：
    #被调用：
    #bug：
    

def delete_60_volume(input_list=[]):
    #作用原理：
    #参数说明：input_list必须有且仅有2个参数。第一个参数为源文件的fullpath，第二参数为target dir path。
    #返回值说明：stdout_err是popen_subj的执行情况的返回结果。
    #举例：
    #调用：
    #被调用：prepare_for_analysis()
    #bug：
    import os
    import shutil
    import subprocess
    
    condition = 'error'
    suffix = '.nii'
    space = ' '
    cmd_link = ' && '
    print('len(input_list):',len(input_list))
    if len(input_list) != 2:
        #raise Exception("incompatible parameter amount ") 
        raise Exception('incompatible parameter amount')
    in_filepath = input_list[0]
    output_filepath = input_list[1]
    temp_filepath = 'temp_240.nii'
    numb_unneeded_volumes = str(300-60-1)
    #cmd_2的内容：3dTcat -prefix subj_240_9_BOLD_tcat.nii.gz subj_240_9_BOLD.nii.gz[10..$]
    cmd_2 = r'3dTcat -prefix ' +  temp_filepath  + ' \'' + in_filepath + r'[' + \
                                                         '0' + r'..' + numb_unneeded_volumes + r']' + '\'' 
    print('cmd_2:',cmd_2)
    #cmd_3的内容：mv  output_filepath  in_filepath
    cmd_3 = r'mv ' + temp_filepath  + space + output_filepath
    print('cmd_3:',cmd_3)
    shell_script = cmd_2 + cmd_link + cmd_3
    print(' shell_script: ',shell_script)
    popen_subj = subprocess.Popen(shell_script,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    stdout_err = popen_subj.communicate()
    if condition in stdout_err[1].decode().lower():
        print('error in delete_60_volume')
    
    
    
def move_files(source_top_path,subj_name,target_top_path,volume_numb,index,modality_dict):
    #作用原理：
    #参数说明：
    #参数说明：  
    #返回值说明：
    #举例：
    #调用：os shutil glob
    #被调用： xuanwu_file_filter
    #调用要求 import os  import shutil
    #bug：
    import os
    subj_dir = os.sep + r'subj_'
    file_4D_name = os.sep + r'4D*.nii'
    target_file_extend = r'.nii'
    t_medi = target_top_path + subj_dir + index
    print('t_medi:',t_medi)
    for key in modality_dict.keys():
        #构造输出文件夹结构
        output_dir_path = t_medi + modality_dict[key] 
        output_file_path = t_medi + modality_dict[key] + subj_dir + index + r'_' + modality_dict[key].replace(os.sep,'') + target_file_extend
        print('output_file_path:',output_file_path)
        if not os.path.exists(output_dir_path):
            os.makedirs(output_dir_path)
        
        if  modality_dict[key] == os.sep + r'BOLD':
            #concatenate_nii(item,output_dir_path)  由于没有相应的软件，故此函数用dcm2niigui手动处理代替，生成的
            #4D文件放在同名文件夹下，然后用下面的代码复制到输出文件夹。
            input_file_path_blur = source_top_path + modality_dict[key]  +  os.sep + subj_name + '*' + os.sep + file_4D_name
            print('boldboldboldboldboldbold')
            print('input_file_path_blur',input_file_path_blur)
            input_file_path = glob.glob(input_file_path_blur)[0]
            print('input_file_path',input_file_path)
            print('output_dir_path',output_file_path)
            shutil.copy2(input_file_path,output_file_path)   
            if volume_numb == '301':
                print('!!!!!!!!!!!!!!!!!preparing to delete_60_volume')
                input_list=[output_file_path,output_file_path] 
                delete_60_volume(input_list)
            
        else :
            input_file_path_blur = source_top_path + modality_dict[key] + os.sep + '*' + subj_name + '*'
            print('otherotherotherotherother')
            print('input_file_path_blur:',input_file_path_blur)
            input_file_path = glob.glob(input_file_path_blur)[0]
            print('input_file_path',input_file_path)
            print('output_dir_path',output_file_path)
            shutil.copy2(input_file_path,output_file_path)
            
#%%
#--------------------------------------------以下内容为主函数
def xuanwu_file_filter(source_top_path ,target_top_path ):
    
    #作用原理：
    #参数说明：
    #参数说明：
    #返回值说明：
    #举例：
    #调用：
    #被调用：
    #bug：
    import os 
    #参数准备
    subj_240_dir = os.sep + r'subj_240_'
    subj_300_dir = os.sep + r'subj_300_'
    modality_key = ['pd_dir','t1_dir','pet_dir','asl_dir','cbf_dir','bold_dir']
    modality_dir = [os.sep+'PD',os.sep+'T1',os.sep+'PET',os.sep+'ASL',os.sep+'CBF',os.sep+'BOLD']
    print('modality_dir:',modality_dir)
    modality_dict = dict(zip(modality_key,modality_dir))
    print('modality_dict:',modality_dict)
    padding = 3
    if not os.path.exists(target_top_path):
        os.makedirs(target_top_path)
    err_log_path = target_top_path + os.sep + sys._getframe().f_code.co_name + '_err_log.txt'
    bold_dirs = glob.glob(source_top_path + modality_dict['bold_dir'] + os.sep + r'*BOLD')
    print(source_top_path + modality_dict['bold_dir'] + os.sep + r'*BOLD')
    print('bold_dirs:',bold_dirs)
    subjname_map_list = []
    excel_path = target_top_path + os.sep + r'subjname_map.xlsx'
    print('excel_path:',excel_path)
    #bold_dirs
    i = 1; j = 1; k = 1; l = 1
    
    for item in bold_dirs :
        print('iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii:',i)
        print('item:',item)
        subj_name = extract_name(item)
        print('subj_name:',subj_name)
        if len(os.listdir(item)) == 241:
            index = str(i).zfill(padding)
            volume_numb = '241'
            print('volume_numb:',volume_numb)
            print('index:',index)
            try:
                move_files(source_top_path,subj_name,target_top_path,volume_numb,index,modality_dict)
            except:
                item = item + '  ' + str(241)
                err_log_write(err_log_path,item,i,j)
            finally: 
                subjname_map_list.append([subj_name,subj_240_dir.replace(os.sep,'')+str(j)])
                j = j + 1
        elif len(os.listdir(item)) == 301:
            index = str(i).zfill(padding)
            volume_numb = '301'
            print('volume_numb:',volume_numb)
            print('index:',index)
            try:
                move_files(source_top_path,subj_name,target_top_path,volume_numb,index,modality_dict)
            except:
                item = item + '  ' + str(301)
                err_log_write(err_log_path,item,i,k)
            finally:
                subjname_map_list.append([subj_name,subj_300_dir.replace(os.sep,'')+str(k)])
                k = k + 1
        else:
            print('l:',l)
            err_log_write(err_log_path,item + r': wrong number of file',i,l)
            l = l + 1
        i = i + 1
        
    subjname_map_df = pd.DataFrame(subjname_map_list)
    subjname_map_df.to_excel(excel_path,sheet_name='Sheet1')

#%%

#xuanwu_file_filter(source_top_path = r'/media/root/Elements3/XuanWu_dpabi_last/原始数据',\
#               target_top_path = r'/media/root/Elements3/XuanWu_dpabi_last/regular')

